package org.budo.dubbo.protocol.http.dispatcher.servlet;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.budo.dubbo.protocol.http.exception.remoting.InterfaceMissMatchException;
import org.budo.dubbo.protocol.http.exception.remoting.RemotingRuntimeException;
import org.budo.dubbo.protocol.http.invocation.adapter.ProtocolRequest;

/**
 * @author li
 */
public class ServletProtocolRequest implements ProtocolRequest {
    private HttpServletRequest request;

    public ServletProtocolRequest(HttpServletRequest request) {
        this.request = request;
    }

    public HttpServletRequest getRequest() {
        return this.request;
    }

    @Override
    public String getHeader(String name) {
        String header = request.getHeader(name);
        if (null != header && !header.isEmpty()) {
            return header;
        }

        return request.getParameter(name);
    }

    @Override
    public String getRemoteAddr() {
        return request.getRemoteAddr();
    }

    @Override
    public Integer getRemotePort() {
        return request.getRemotePort();
    }

    @Override
    public String getInterfaceName() {
        throw new RuntimeException();
    }

    @Override
    public String getMethodName() {
        throw new RuntimeException();
    }

    @Override
    public Map<String, Object> getArguments() {
        throw new RuntimeException();
    }

    @Override
    public String getRequestId() {
        throw new RuntimeException();
    }

    @Override
    public String toString() {
        return super.toString() //
                + ", request=" + request //
                + ", serverName=" + request.getServerName() //
                + ", requestUri=" + request.getRequestURI() //
                + ", remoteAddr=" + request.getRemoteAddr() //
                + ", userAgent=" + request.getHeader("User-Agent");
    }

    /**
     * 将请求地址解析为接口名和方法名
     */
    public static String[] parseUrlToTypeAndMethod(ProtocolRequest protocolRequest) {
        ServletProtocolRequest servletRequest = (ServletProtocolRequest) protocolRequest;
        HttpServletRequest httpRequest = servletRequest.getRequest();

        boolean IS_POST_REQUEST = "POST".equalsIgnoreCase(httpRequest.getMethod());

        String requestUri = httpRequest.getRequestURI();
        int lastDotIndex = requestUri.lastIndexOf('.');

        if (lastDotIndex < 0) {
            if (!IS_POST_REQUEST) { // GET 请求，不抛出异常
                return null;
            }

            throw new InterfaceMissMatchException(requestUri, null);
        }

        String methodName = requestUri.substring(lastDotIndex + 1);

        int lastVirguleIndex = requestUri.lastIndexOf('/');
        if (lastVirguleIndex < 0) {
            if (!IS_POST_REQUEST) {
                return null;
            }

            String message = "#63 requestUri=" + requestUri + ", lastVirguleIndex=" + lastVirguleIndex + ", lastDotIndex=" + lastDotIndex //
                    + ", protocolRequest=" + protocolRequest;
            throw new RemotingRuntimeException(message);
        }

        if (lastVirguleIndex + 1 >= lastDotIndex) {
            if (!IS_POST_REQUEST) {
                return null;
            }

            String message = "#80 requestUri=" + requestUri + ", lastVirguleIndex=" + lastVirguleIndex + ", lastDotIndex=" + lastDotIndex //
                    + ", protocolRequest=" + protocolRequest;
            throw new RemotingRuntimeException(message);
        }

        String interfaceNameInUrl = requestUri.substring(lastVirguleIndex + 1, lastDotIndex);

        return new String[] { interfaceNameInUrl, methodName };
    }
}